import json
import numpy as np
import math
from utils.getDataFromMysql import *
from utils.expand import *

class AttributeNode:
    def __init__(self, title_name, year, data, country, unitsWithNorm, countryWithNorm):
        self.title_name = title_name
        self.year = year
        self.data = data
        self.country = country
        self.units_with_norm = unitsWithNorm
        self.country_with_norm = countryWithNorm

    @property
    def title_name(self):
        return self.__title_name

    @title_name.setter
    def title_name(self, title_name):
        self.__title_name = title_name

    @property
    def year(self):
        return self.__year

    @year.setter
    def year(self, year):
        self.__year = year

    @property
    def data(self):
        return self.__data

    @data.setter
    def data(self, data):
        self.__data = data

    @property
    def country(self):
        return self.__country

    @country.setter
    def country(self, country):
        self.__country = country

    @property
    def units_with_norm(self):
        return self.__units_with_norm

    @units_with_norm.setter
    def units_with_norm(self, units_with_norm):
        self.__units_with_norm = units_with_norm

    @property
    def country_with_norm(self):
        return self.__country_with_norm

    @country_with_norm.setter
    def country_with_norm(self, country_with_norm):
        self.__country_with_norm = country_with_norm

def safe_convert_to_float(value):
    try:
        return float(value)
    except ValueError:
        return 0.0

@timecost
def generateScatterLineChart(result_list: list) -> str:
    json_result = {
        "echartX": [],
        "echartNav": [],
        "columns": [],
        "tableData": [],
        "echartY": [],
        "echartDataAxis": []
    }

    if not result_list:
        return json.dumps(json_result)

    year_list = [item.year for item in result_list if item.year]
    unique_year_list = np.unique(year_list).tolist()
    json_result["echartX"] = unique_year_list

    title_list = [f"{item.country}_{item.norm}_{item.units}" for item in result_list]
    unique_title_list = np.unique(title_list).tolist()
    json_result["echartNav"] = unique_title_list

    attribute_list = [
        AttributeNode(f"{item.country}_{item.norm}_{item.units}", item.year, item.data_value, item.country, f"{item.norm}({item.units})", f"{item.country}_{item.norm}")
        for item in result_list
    ]

    columns = [{'prop': 'year', 'label': '年份'}]
    unique_titles = {obj.title_name for obj in attribute_list}
    columns.extend({'prop': title, 'label': title} for title in unique_titles)
    json_result["columns"] = columns

    table_data = []
    for year in unique_year_list:
        row = {'year': year}
        for column in columns[1:]:
            result = next((obj for obj in attribute_list if obj.year == year and obj.title_name == column['prop']), None)
            row[column['prop']] = result.data if result else ''
        table_data.append(row)
    json_result['tableData'] = table_data

    unique_units_with_norm_list = {obj.units_with_norm for obj in attribute_list}
    echartY = []
    for index, unit_with_norm in enumerate(unique_units_with_norm_list):
        data = [safe_convert_to_float(obj.data) for obj in attribute_list if obj.units_with_norm == unit_with_norm]
        max_value = max(data, default=0)
        interval = math.ceil(max_value / len([d for d in data if d != 0])) if max_value > 0 else 1
        echartY.append({
            'name': unit_with_norm,
            'type': 'value',
            'min': 0,
            'max': max_value,
            'interval': interval,
            'position': 'left' if index % 2 == 0 else 'right'
        })
    json_result['echartY'] = echartY

    echartDataAxis = []
    for index, unit_with_norm in enumerate(unique_units_with_norm_list):
        data_country_norm = [obj.country_with_norm for obj in attribute_list if obj.units_with_norm == unit_with_norm]
        name = data_country_norm[0] if data_country_norm else ''
        data = [safe_convert_to_float(obj.data) for obj in attribute_list if obj.units_with_norm == unit_with_norm]
        echartDataAxis.append({
            'type': 'line' if index % 2 == 0 else 'scatter',
            'yAxisIndex': 0 if index % 2 == 0 else 1,
            'name': name,
            'data': data
        })
    json_result['echartDataAxis'] = echartDataAxis

    return json.dumps(json_result)


if __name__ == '__main__':
    sql_query = "select * from weo_data where country = 'Afghanistan' and norm in ('NGDP_R','NGDP_RPCH') "
    result_list = getDataBySql(sql_query)

    response = generateScatterLineChart(result_list)
    print(response)